<?php

namespace Yiru\LaravelComposer\Console\Commands;

use Illuminate\Console\Command;
use Symfony\Component\Console\Input\InputOption;
use Illuminate\Support\Str;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Auth;
use Log;
use DB;
use Exception;

use Josh\Terminal\TerminalFacade    as Terminal;
use mikehaertl\shellcommand\Command as Shell;               //https://github.com/mikehaertl/php-shellcommand
use October\Rain\Config\DataWriter\Rewrite as Config;
use Webimpress\SafeWriter\FileWriter;
use Yiru\LaravelComposer\Helpers\Npm;

class NpmRemove extends Command
{    
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'npm:remove {pkgs}';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Remove npm pacakge, clean config/migration/view/table etc';
    
    public function __construct()
    {
        parent::__construct();        
    }

    /**
     * Execute the console command.
     *
     * @return mixed
     */
    public function handle()
    {
         $pkgs = $this->argument('pkgs')?:null;
        // dump(config('npm'));
        if($pkgs=='all'){
            [$pkgs,$configs] = Arr::divide(config('npm'));
        }else $pkgs = explode(',',$pkgs);
        
        $this->undo_require($pkgs);        

        foreach ($pkgs as $pkg) {
            $this->undo_env(Npm::envName($pkg));
        }        
    }
     
    /**
     * Composer Remove package
     * @return bool
     */
    public function undo_require($pkgs)
    {
        $npmNames="";        
        if(!is_array($pkgs)) $pkgs=[$pkgs];
        foreach ($pkgs as $pkg) {
            $npmPkg  = Npm::getPkg($pkg);
            $npmName = Npm::getName($pkg);
            $npmNames = Str::of($npmNames)->append(" ".$npmName);
            Arr::set($envPkgs,$npmPkg,Npm::envName($pkg));
            $npmVer=Npm::getVer($pkg);
            if(Str::of($npmVer)->isEmpty()) {
                $shell= new Shell('npm list '.$npmName.' version');
                $shell->setOptions([
                    'procEnv' => [
                        'PATH'=>"\$PATH:/usr/local/node/bin"
                    ]
                ]);
                $ret=Npm::shell($shell,$this->output,"NPM_LIST");
                if(is_bool($ret) && !$ret) continue;
                dump($ret);
                dump('/('.$npmName.'@[\S]*)/');
                $npmNameReg=Str::of($npmName)->replaceMatches('/[\/]/', function ($match) {
                                                    return '\\'.$match[0];
                                                });
                $retPkg=Str::of($ret)->matchAll('/('.$npmNameReg.'@[\S]*)/')->first();
        
                $npmVer=String($retPkg)->segment('@',1);
                if(Str::of($npmVer)->isEmpty()) continue;
            }
            $this->undo_deploy($pkg,$npmVer);            
        }        
        
        $shell= new Shell('npm uninstall --verbose '.$npmNames);
        $shell->setOptions([
            'procEnv' => [
                'PATH'=>"\$PATH:/usr/local/node/bin"
            ]
        ]);
        $ret=Npm::shell($shell,$this->output,"NPM_UNINSTALL");
    }
       

    /**
     * unDeploy
     * @return bool
     */
    public function undo_deploy($pkg)
    {
        if(empty($pkg)){
            throw new Exception('必须提供包与版本');
        }
        $target_dir=Npm::getEnvDir($pkg);          
        dump($pkg);
        dump($target_dir);
        $ret='';
        if(file_exists($target_dir)){
             $shell= new Shell('rm -rdf '.$target_dir);
             $ret=Npm::shell($shell,$this->output,"remove directory");             
        }
        if(count(glob(dirname($target_dir).'/*'))===0){
            $shell= new Shell('rm -rdf '.dirname($target_dir));
            $ret=$ret.Npm::shell($shell,$this->output,"remove parent emtpy directory");
        }
        return $ret;
    }

    /**
     * unDeploy
     * @return bool
     */
    public function undo_env($pkg)
    {
        $envItems=config('npm.pkgs.'.$pkg.'.envs');
        if(!empty($envItems)){            
            foreach ($envItems as $key) {
                $shell=new Shell('php artisan dotenv:delete-key '.$key);
                Npm::shell($shell,$this->output,"env delete key failed");
            }
        }
        $shell=new Shell('php artisan config:cache');    
        Npm::shell($shell,$this->output,"config:cache failed");
    }

    protected function getOptions()
    {
        return [
            ['config',   'c', InputOption::VALUE_OPTIONAL, 'remove config'],
            ['env',      'e', InputOption::VALUE_OPTIONAL, 'remove env'],
            ['publish',  'p', InputOption::VALUE_OPTIONAL, 'remove publish'],
            ['route',    'r', InputOption::VALUE_OPTIONAL, 'remove route'],
            ['migration','m', InputOption::VALUE_OPTIONAL, 'remove migration']            
        ];
    }

}
